#pragma once
#include "base/noncopyable.h"

namespace net_tools::base{
class Memorypool;
class Base_buffer : public noncopyable{
 public:
  Base_buffer(int block_number);
  ~Base_buffer();
  static void Singleton_pool(int mempool_block_size,int mempool_block_number);

  void Read_append(int append_byte){
    read_index_ += append_byte;
  };
  void Write_append(int append_byte){
    write_index_ += append_byte;
  };

  void Write(void* buf,unsigned int size);

  Base_buffer* Get_next(){
    return next_;
  };
  Base_buffer* Get_pre(){
    return before_;
  };
  unsigned int Get_read_residue(){
    return write_index_ - read_index_;
  };
  unsigned int Get_write_residue(){
    return buf_size_ - write_index_;
  };
  void Clear_index(){
    read_index_ = 0;
    write_index_ = 0;
  };
  // write_index == buf_size
  bool Is_full(){
    return write_index_ == buf_size_;
  };
  // write_index == read_index
  bool Is_empty(){
    return write_index_ == read_index_;
  };

  // self -> other => self -> next -> other
  void Insert_next(Base_buffer* next);
  // other -> self => other -> pre -> self
  void Insert_pre(Base_buffer* pre);

  unsigned int Get_write_index(){
    return write_index_;
  };
  unsigned int Get_buf_size(){
    return buf_size_;
  };

  char* Write_index(int index = 0){
    return reinterpret_cast<char*>(buf_) + write_index_ + index;
  };
  // only for read,dont change index
  char* operator[](unsigned int index);

 private:
  void*          buf_;
  unsigned int   write_index_;
  unsigned int   read_index_;
  volatile bool  free_;
  unsigned int   buf_size_;
  Base_buffer*   next_;
  Base_buffer*   before_;
  static Memorypool* mempool_;

}__attribute__((aligned(64)));

} // net_tools::base